xlv.obj.channel={
	extend:function(){
		this.extend('xlv.obj.webObject');
	},
	implement:function(){
	},
	properties:{
		name:'gae-channel',
		objectURL:'channel',
		globe:true,
		id:null,
		autoSetup:false,
		propXPath:'properties'
	},
	method:{
		construct:function(){
			if(this.$P.autoSetup){
				this.$P.methodName='get-token';
				this._setup();
			}
		},
		_setup:function(){
			var script = document.createElement('script');
			script.src = '/_ah/channel/jsapi';
			script.type = 'text/javascript';
			document.body.appendChild(script);
			this.$V.setup=true;
		},
		initial:function(){
			xlv.channel=this;
			this.$super('xlv.obj.webObject.initial');
			this.$V.id=(this.$P.id||xlv.sys.xSessionId);
			this.setWebObjectProperties({'get-token':{'id':this.$V.id}});
		},
		webObjectResponse:function(){
			this.$super('xlv.obj.webObject.webObjectResponse');
			var v=this.$V;
			if('get-token'==this.xml_responseMethodNames()){
				v.token=null;
				if('true'==this.getValue('get-token.return.valid'))	{
					v.token=this.getValue('get-token.return.token');
					setTimeout((function(){this._openChannel();}).bind(this),500);
				}
			}
		},
		returnDataManage:function(clone_response){
			if('receive-message' != this.xml_responseMethodNames())return this.$super('xlv.obj.webObject.returnDataManage',clone_response);
			var rm=this.xml_selectSingleNode('properties/receive-message');
			var m=this.xml_selectSingleNode('receive-message/message',this.xml_properties.responseXML.documentElement);
			rm.appendChild(this.xml_adoptNode(m));
		},
		_openChannel:function(){
			try{
				if(goog) return this.openChannel();
			}catch(e){}
			setTimeout((function(){this._openChannel();}).bind(this),300);
		},
		openChannel:function(){
			if(this.$V.token && this.$V.channel && this.$V.socket) return this.closeChannel();
			if(this.$V.token && !this.$V.channel && !this.$V.socket){
				var v=this.$V;
				v.channel = new goog.appengine.Channel(v.token);
				var on={onopen:function(){this._opened();}.bind(this),
						onmessage:function(msg){this._message(msg);}.bind(this),
						onerror:function(msg){this._error(msg);}.bind(this),
						onclose:function(){this._close();}.bind(this)
						};
				v.socket = v.channel.open(on);
			}else{
				if(!this.$V.setup)this._setup();
				this.webMethod('get-token');
			}
		},
		closeChannel:function(){
			if(this.$V.socket)this.$V.socket.close();
			this.$V.token=null;
			this.$V.channel=null;
			this.$V.socket=null;
		},
		_opened:function(){
			this.setValue(this.$V.id,'opened.id');
			this.webMethod('opened');
		},
		_message:function(msg){
			var xml=(msg&&msg.data)? this.xml_stringToNode(msg.data):null;
			if(xml){
				var p=this.xml_properties;
				var doc=Prototype.Browser.IE ? new ActiveXObject('Msxml2.DOMDocument'):document.implementation.createDocument("", "", null);
				doc.appendChild((doc.adoptNode)?doc.adoptNode(xml):xml);
				p.responseXML=doc;
				if(Prototype.Browser.IE)p.responseXML.setProperty('SelectionLanguage','XPath');
				if(p.currentXML == null) p.currentXML=p.responseXML;
				this.xml_response();
			}
			return true; 
		},
		_error:function(msg){
			this.$V.token=null;
			this.$V.channel=null;
			this.$V.socket=null;
		},
		_close:function(){
			this.setValue(this.$V.id,'close.id');
			this.webMethod('close');
			if(!this.$V.dead) this.openChannel();
		},
		sendMessage:function(id,name,type,data){
			this.setValue(this.getValue('opened.id'),'send-message.sender.id');
			this.setValue(this.getValue('opened.name'),'send-message.sender.name');
			this.setValue(this.getValue('opened.type'),'send-message.sender.type');
			this.setValue((id||''),'send-message.receiver.id');
			this.setValue((name||''),'send-message.receiver.name');
			this.setValue((type||''),'send-message.receiver.type');
			var dn=this.getNode('send-message.data');
			while(dn.firstChild)dn.removeChild(dn.firstChild);
			if(Object.isString(data))xlv.util.setXmlText(dn,data);
			else if(Object.isElement(data)){
				dn.appendChild(this.xml_adoptNode(data.cloneNode(true)));
			}else {
				var j={'root':data};
				var d=this.xml_stringToNode(json2xml(j,''));
				d=this.xml_adoptNode(d);
				while(d.firstChild)	dn.appendChild(d.firstChild);
			}
			this.webMethod('send-message');
		},
		getMessageCount:function(){
			var ms=this.xml_selectNodes('properties/receive-message/message');
			return ms ? ms.length:0;
		},
		getMessage:function(index){
			if(Object.isUndefined(index)) return this.getLastMessage();
			var ms=this.xml_selectNodes('properties/receive-message/message');
			var m=ms[index];
			return (m)? xml2json(m,'').evalJSON():null;
		},
		getLastMessage:function(){
			var ms=this.xml_selectNodes('properties/receive-message/message');
			return (ms && ms.length>0)? xml2json(ms[ms.length-1],'').evalJSON():null;
		},
		removeAllMessages:function(){
			var m=this.xml_selectSingleNode('properties/receive-message');
			while(m.firstChild)m.removeChild(m.firstChild);
		}
	}
};

